﻿package com.game.engine
{
	import base.BaseGameScene;
	import base.BaseMonster;
	
	import com.dusk.game.Logger;
	import com.dusk.net.AssetBundle;
	import com.dusk.net.AssetManager;
	import com.dusk.net.AssetType;
	import com.dusk.tool.KeyBoarder;
	import com.dusk.util.McUtil;
	import com.dusk.util.ResUtil;
	import com.game.ctrler.BattleCamera;
	import com.game.ctrler.GadgetQueue;
	import com.game.ctrler.GameKeyInput;
	import com.game.ctrler.GameLogicCtrler;
	import com.game.ctrler.GameViewCtrler;
	import com.game.data.constant.FrameRate;
	import com.game.data.vo.BattleCacheDataVO;
	import com.game.data.vo.HeroGroupVO;
	import com.game.data.vo.LevelConfigVO;
	import com.game.engine.nape.Nape;
	import com.game.manager.EventManager;
	import com.game.manager.GameSceneManager;
	import com.game.manager.SettingManager;
	import com.game.manager.SoundManager;
	import com.game.view.component.FloorBg;
	import com.game.view.component.TransDoor;
	import com.game.view.layer.GameCartoon;
	import com.game.view.layer.GameInfo;
	import com.game.view.layer.loadingBar.LoadingBar2;
	import com.greensock.TweenMax;
	
	import config.Config;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;
	
	public class MainGame extends EventDispatcher
	{
		
		private static var _instance:MainGame;
		
		public var levelData:LevelConfigVO;
		public var battleData:BattleCacheDataVO;
		public var team:HeroGroupVO;
		
		public var gameCtrl:GameLogicCtrler;
		public var viewCtrl:GameViewCtrler;
		public var gadgetQueue:GadgetQueue;
		public var root:Sprite;
		private var _isStepping:Boolean = false;
		private var _ticker:uint = 0;
		private var _frameFreeze:int = 0;
		
		public static function getIns():MainGame
		{
			return _instance;
		}
		
		private function get gc():Config
		{
			return Config.getIns();
		}
		
		public function MainGame(root:Sprite,cStage:int = 1,cLevel:int = 1)
		{
			super();
			if(_instance) _instance.destroyGame();
			_instance = this;
			init(root,cStage,cLevel);
		}
		
		private function init(container:Sprite,cStage:int = 0,cLevel:int = 0):void
		{
			gc.isInBattle = true;
			root = container;
			initLevelData(cStage, cLevel);
			
			showCartoon();
		}
		
		public function showCartoon():void
		{
			if(levelData.levelStartCartoon)
			{
				var cartoon:GameCartoon = new GameCartoon();
				cartoon.show(levelData.levelStartCartoon,GameCartoon.FIGHT,true);
				cartoon.addEventListener(GameCartoon.SHOW_CARTOON_OVER,loadAssets);
			}
			else
			{
				loadAssets();
			}
		}
		
		private function loadAssets(...rest):void
		{
			if(rest.length)
			{
				(rest[0].target as GameCartoon).removeEventListener(GameCartoon.SHOW_CARTOON_OVER,loadAssets);
			}
			var bar:LoadingBar2 = new LoadingBar2();
			bar.name = "loadingBar";
			GameSceneManager.getIns().addScene(bar,"top");
			AssetManager.getIns().loadAssets(AssetBundle.getInBattleAssets(levelData),
					AssetType.SWF,null,
					newGame,bar.onProgress,null);
		}
		
		public function createMonster(kind:int,xx:int,yy:int):BaseMonster
		{
			var mon1:BaseMonster;
			var minIdx:int = 0;
			try
			{
				mon1 = ResUtil.getNewObj("export.monster.Monster" + kind);
				mon1.x = xx;
				mon1.y = yy;
				gc.pWorld.getMonsterArray().push(mon1);
				minIdx = viewCtrl.getMinIdxInHeroAndPet();
				gc.gameScene.addChildAt(mon1, minIdx);
				return mon1;
			} catch (e:Error)
			{
				Logger.log("生成怪物--------->Monster" + kind + "失败");
				Logger.log(e.message);
				Logger.log(e.getStackTrace());
				return null;
			}
		}
		
		public function freezeFrame(frameCount:int):void
		{
			_frameFreeze = frameCount;
		}
		
		public function newGame():void
		{
			gc.pWorld = new PhysicsWorld();
			//初始化控制器
			gc.keyboardControl = new GameKeyInput();
			gc.keyboardControl.setKeyConfig(gc.keyConfig);
			gc.keyboardControl.setKeyboard(new KeyBoarder(GameSceneManager.getIns().mainStage));
			gc.keyboardControl.addListenFunction(functionControl);
			gameCtrl = new GameLogicCtrler(this);
			viewCtrl = new GameViewCtrler(this);
			gadgetQueue = new GadgetQueue();
			initScene();
			gc.vController = new BattleCamera();
			initRoleGroup();
			//初始化角色组
			initGameInfo();
			
			battleData.startTime = getTimer();
			McUtil.checkLoadOK(gc.gameScene, nextDoAfterLoad);
		}
		
		private function initLevelData(cStage:int, cLevel:int):void
		{
			levelData = gc.configManager.levelProxy.getLevelConfigById(cStage.toString() + "_" + cLevel.toString());
			battleData = new BattleCacheDataVO();
			Logger.log("关卡ID: " + levelData.levelID);
		}
		
		private function nextDoAfterLoad():void
		{
			gc.pWorld.pWorldInit();
			(GameSceneManager.getIns().getChildByName("loadingBar") as LoadingBar2).removeFromParent();
			if (levelData.bgmName != null)
			{
				SoundManager.playBgm(levelData.bgmName);
			}
			else
			{
				SoundManager.playBgm("begin");
			}
			startStep();
		}
		
		public function startStep():void
		{
			_isStepping = true;
			if(gc.frameClips != SettingManager.getSettingVO().battleFPS) gc.frameClips = SettingManager.getSettingVO().battleFPS;
			if (!root.hasEventListener(Event.ENTER_FRAME))
			{
				root.addEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			root.addEventListener(MouseEvent.CLICK, setFocus);
			setFocus();
			gc.isStopGame = false;
		}
		
		public function stopStep():void
		{
			_isStepping = false;
			root.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			root.removeEventListener(MouseEvent.CLICK, setFocus);
			gc.isStopGame = true;
		}
		
		public function functionControl(evt:KeyboardEvent):void
		{
			if(gc.keyboardControl.isOpenBag())
			{
				gc.gameInfo.roleInfo.btn_pack.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
			if(gc.keyboardControl.isOpenSkill())
			{
				gc.gameInfo.roleInfo.btn_skill.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
			if(gc.keyboardControl.isOpenSetting())
			{
				gc.gameInfo.roleInfo.btn_set.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
		}
		
		private function setFocus(evt:MouseEvent = null):void
		{
			if (root)
			{
				root.stage.focus = root.stage;
			}
		}
		
		private function onEnterFrame(param1:Event):void
		{
			if(!_isStepping)
			{
				return;
			}
			if(battleData.levelPassed && gc.pWorld.getMonsterArray().length == 0 && !battleData.doorShowed)
			{
				showDoor();
			}
			_ticker++;
			if(_frameFreeze-- > 0) return;
			var ratio:Number = gc.frameClips / FrameRate.GAME_FRAME_RATE_EPOCH;
			var isRenderAnimate:Boolean = (_ticker % ratio == 0);
			gc.gameInfo.render(ratio);
			gc.vController.render(ratio);
			gc.pWorld.render(ratio);//这里将render和renderAnimate合并了,防止二次循环
			if(isRenderAnimate)
			{
				gc.gameInfo.renderAnimate();
				gc.vController.renderAnimate();
				gc.pWorld.renderAnimate();
				gadgetQueue.renderAnimate();
			}
		}
		
		public function showDoor():void
		{
			for each(var i:TransDoor in gc.pWorld.getTransferDoorArray())
			{
				i.visible = true;
			}
			battleData.doorShowed = true;
		}
		
		public function isInSea():Boolean
		{
			return false;
			var stageNum:int = levelData.getLevelIDArray()[0];
			return stageNum == 3;
		}
		
		public function initScene():void
		{
			gc.floorBackGround = new FloorBg("floorBg" + levelData.getLevelIDArray()[0].toString());
			root.addChild(gc.floorBackGround);
			
			
			var scene:BaseGameScene = ResUtil.getNewObj("export.gameScene.sl" + levelData.curStage + levelData.curLevel) as BaseGameScene;
			if (scene == null)
			{
				Logger.logError("找不到游戏前景", this);
				CONFIG::DEBUG{
					Logger.logError("可能是场景路径出错或者场景未继承自BaseGameScene",this);
				}
			}
			scene.buildScene(levelData);
			gc.gameScene = scene;
			root.addChild(gc.gameScene);
		}
		
		public function initGameInfo():void
		{
			gc.gameInfo = new GameInfo();
			if(gc.team.hero)
			{
				gc.gameInfo.setRole(gc.team.hero,1);
			}
			gc.gameInfo.init();
			root.addChild(gc.gameInfo);
		}
		
		public function initRoleGroup():void
		{
			var team:HeroGroupVO = new HeroGroupVO();
			if (gc.playerData.roleId > 0)
			{
				team.hero = team.createHero(gc.playerData);
				gc.gameScene.addChild(team.hero);
				gc.pWorld.getHeroArray().push(team.hero);
				gc.vController.setRole1(team.hero)
			}
			gc.team = team;
		}
		
		public function destroyGame():void
		{
			stopStep();
			gc.gameScene.destroy();
			gc.gameScene = null;
			gc.pWorld.destroy();
			gc.pWorld = null;
			gc.gameInfo.destroy();
			gc.gameInfo = null;
			gc.keyboardControl.destroy();
			gc.keyboardControl = null;
			gc.vController.destroy();
			gc.vController = null;
			gc.floorBackGround.destroy();
			gc.floorBackGround = null;
			gc.team.destroy();
			gc.team = null;
			EventManager.getIns().removeAll();
			battleData.destroy();
			gameCtrl.destroy();
			viewCtrl.destroy();
			gadgetQueue.destroy();
			TweenMax.killAll(false);
			gc.frameClips = FrameRate.GAME_FRAME_RATE_LOW;
			gc.isInBattle = false;
			root = null;
			_instance = null;
		}
	}
}
